jfblog

Random logs and notes

Hamming_code

Hamming (7,4) coding

A colleague of mine asked me about a simple demonstration of Hamming code. It is inspired by this link, but unfortunately the code is not available anymore. Below is what I did.

Two utilitary functions

For encoding and decoding to and from binary number representations

In [2]:
from random import randint
import numpy as np

# We begin with two utilitary functions
def dec2binmat(n):
    #This converts a decimal number into a matrix of (int) bits
    ll=list("{0:04b}".format(n)) #.format give a string which is converted to a list
    ll=[int(k) for k in ll] # for each element in the list convert to int
    return np.matrix(ll) # return a matrix

def binmat2dec(m):
    #This converts a matrix of (int) bits into a decimal number 
    m=m.reshape(1,size(m),order='C').tolist()[0] # convert to list
    s=0
    l=len(m)-1
    for k,v in enumerate(m):
        s+=m[k]*2**(l-k)
    return s

# examples
n=5
m=dec2binmat(n)
print("Number {} converted into binary: {}".format(n,m))
nn=binmat2dec(m)
print("And back to a decimal number: {}".format(nn))
Number 5 converted into binary: [[0 1 0 1]]
And back to a decimal number: 5

Hamming(7,4) Codec

In [27]:
#Method to encode message
def encode(message):
    # message: binary string representation of the (int) number
      
    message = np.matrix(message)
    #print(message)
    
    #Hamming (7,4) generating matrix to encode the message
    g = np.matrix([[1, 0, 0, 0, 0, 1, 1],
                   [0, 1, 0, 0, 1, 0, 1],
                   [0, 0, 1, 0, 1, 1, 0],
                   [0, 0, 0, 1, 1, 1, 1]])
    #Multiply the message with the matrix to encode the message with module 2
    return ( message * g ) % 2

#Method to decode message
def decode(message):
     
    #Matrix to decode the message
    h = np.matrix([[0, 0, 0, 1, 1, 1, 1],
                   [0, 1, 1, 0, 0, 1, 1],
                   [1, 0, 1, 0, 1, 0, 1]])
    #Multiply the message with the matrix to verify the message with module 2
    #This is the syndrom
    hy = ( h * message.T)  % 2  #%2 is the modulo 2 operation
    
    #Get the integer value of the binary as result of the previous operation
    #print(hy)
    s=binmat2dec(hy)
    print("Syndrom: ",s)
    #print(s)
    # the syndrom gives the bit number. 
    #Since indexes begin at 0 there is a shift of one
    if s!=0:
        message[0,s-1]=(message[0,s-1]+1) %2
    return (s,message)

A test

And finally a test of encoding-decoding with some corruptions of the message.

In [28]:
def hamm_tst():
    
    n=int(input('Please input a number in [0,15] '))
    if n<0 or n>15:
        print("n must be between 0 and 15")
        raise ValueError
    print('binary number: ', bin(n) )
    b=dec2binmat(n)
    enc=encode(b)
    print('encoded version: ', enc)
    print('decoded version: ', decode(enc))
    print('.'*20)
    print('let us add a random error: ')
    noise=random.randint(0,7) # change one bit among 7 possible
    newenc=enc.copy()
    newenc[0,noise]=(newenc[0,noise]+1) %2
    nb=noise+1        
    print('bit number %d is changed: ' % nb)
    print("new message ",newenc)
   
    print('decoded version: ', decode(newenc)[1])
    print('The End')
    
hamm_tst()
Please input a number in [0,15] 9
binary number:  0b1001
encoded version:  [[1 0 0 1 1 0 0]]
Syndrom:  0
decoded version:  (0, matrix([[1, 0, 0, 1, 1, 0, 0]]))
....................
let us add a random error: 
bit number 3 is changed: 
new message  [[1 0 1 1 1 0 0]]
Syndrom:  3
decoded version:  [[1 0 0 1 1 0 0]]
The End

An object-oriented version

Let us now design an object 'Hamming codec'.

In [29]:
class Hamming_codec():
    def __init__(self):
        self.indata=[[0,0,0,0]]
    def data(self,indata=None):
        if indata:
            indata=list(indata)
            ll=[int(k) for k in indata] # for each element in the list convert to int
            self.indata=np.matrix(ll)
        else:
           self.decode() 
    def code(self,incode=None):
        self.code=encode(self.indata)
        print("Code: ",self.code)
        
    def decode(self,incode=None):  
         if incode:
            indata=list(incode)
            ll=[int(k) for k in indata] # for each element in the list convert to int
            self.code=np.matrix(ll)
         r=decode(self.code)[1]
         print("Decoded value: ",r)
        
In [30]:
t=Hamming_codec()
t.data('1101')
t.code()
t.decode()
print("\nAnd now introduce an error...")
t.decode('1101011')
Code:  [[1 1 0 1 0 0 1]]
Syndrom:  0
Decoded value:  [[1 1 0 1 0 0 1]]

And now introduce an error...
Syndrom:  6
Decoded value:  [[1 1 0 1 0 0 1]]

In [33]:
HTML(the_end(theNotebook))
Out[33]:

This post was written as an IPython notebook. It is available for download or as a static html.

Creative Commons License
jfblog by J.-F. Bercher is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Based on a work at http://jfbercher.github.io/.

misc

Comments